package com.hupu.jrs.widget

import android.annotation.SuppressLint
import android.content.Context
import android.net.Uri
import android.os.Build
import android.text.TextUtils
import android.util.AttributeSet
import android.webkit.*
import com.hupu.jrs.AppManager
import com.hupu.jrs.Constants
import com.hupu.jrs.MyApplication
import com.hupu.jrs.components.retrofit.RequestHelper
import com.hupu.jrs.components.storage.UserStorage
import com.hupu.jrs.ui.browser.BrowserActivity
import com.hupu.jrs.ui.content.ContentActivity
import com.hupu.jrs.ui.imagepreview.ImagePreviewActivity
import com.hupu.jrs.ui.login.LoginActivity
import com.hupu.jrs.ui.post.PostActivity
import com.hupu.jrs.ui.report.ReportActivity
import com.hupu.jrs.ui.thread.list.ThreadListActivity
import com.hupu.jrs.ui.userprofile.UserProfileActivity
import com.hupu.jrs.util.StringUtil
import com.hupu.jrs.util.ToastUtil
import org.json.JSONException
import org.json.JSONObject
import java.net.URLEncoder
import java.util.*
import javax.inject.Inject

/**
 * Created by sll on 2015/12/10.
 */
class HuPuWebView : WebView {

    private var basicUA: String? = null
    private var header: MutableMap<String, String>? = null

    @Inject
    internal var mUserStorage: UserStorage? = null
    @Inject
    internal var mRequestHelper: RequestHelper? = null

    private var callBack: HuPuWebViewCallBack? = null

    var onScrollChangedCallback: OnScrollChangedCallback? = null

    constructor(context: Context) : super(context) {
        init()
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs) {
        init()
    }

    fun setCallBack(callBack: HuPuWebViewCallBack) {
        this.callBack = callBack
    }


    @SuppressLint("WrongConstant")
    private fun init() {
        (context.applicationContext as MyApplication).applicationComponent!!.inject(this)
        val settings = settings
        settings.builtInZoomControls = false
        settings.setSupportZoom(false)
        settings.javaScriptEnabled = true
        settings.allowFileAccess = true
        settings.setSupportMultipleWindows(false)
        settings.javaScriptCanOpenWindowsAutomatically = true
        settings.domStorageEnabled = true
        settings.cacheMode = 1
        settings.useWideViewPort = true
        if (Build.VERSION.SDK_INT > 6) {
            settings.setAppCacheEnabled(true)
            settings.loadWithOverviewMode = true
        }
        settings.cacheMode = WebSettings.LOAD_DEFAULT
        val path = context.filesDir.path
        settings.setGeolocationEnabled(true)
        settings.setGeolocationDatabasePath(path)
        settings.domStorageEnabled = true
        this.basicUA = settings.userAgentString + " kanqiu/7.05.6303/7059"
        setBackgroundColor(0)
        initWebViewClient()
        try {
            if (mUserStorage!!.isLogin) {
                val token = mUserStorage!!.token
                val cookieManager = CookieManager.getInstance()
                cookieManager.setCookie("http://bbs.mobileapi.hupu.com",
                        "u=" + URLEncoder.encode(mUserStorage!!.cookie, "utf-8"))
                cookieManager.setCookie("http://bbs.mobileapi.hupu.com",
                        "_gamesu=" + URLEncoder.encode(token, "utf-8"))
                cookieManager.setCookie("http://bbs.mobileapi.hupu.com", "_inKanqiuApp=1")
                cookieManager.setCookie("http://bbs.mobileapi.hupu.com", "_kanqiu=1")
                CookieSyncManager.getInstance().sync()
            }
        } catch (e: Exception) {
            e.printStackTrace()
        }

    }

    private fun initWebViewClient() {
        CookieManager.getInstance().setAcceptCookie(true)
        webViewClient = HupuWebClient()
    }

    private inner class HupuWebClient : WebViewClient() {
        override fun shouldOverrideUrlLoading(view: WebView, url: String): Boolean {
            val uri = Uri.parse(url)
            val scheme = uri.scheme
            if (url.startsWith("hupu") || url.startsWith("kanqiu")) {
                if (scheme != null) {
                    handleScheme(scheme, url)
                }
            } else if (scheme == "http" || scheme == "https") {
                BrowserActivity.startActivity(context, url)
            }
            return true
        }

        override fun onPageFinished(view: WebView, url: String) {
            super.onPageFinished(view, url)
            if (callBack != null) {
                callBack!!.onFinish()
            }
        }

        override fun onReceivedError(view: WebView, request: WebResourceRequest, error: WebResourceError) {
            super.onReceivedError(view, request, error)
            if (callBack != null) {
                callBack!!.onError()
            }
        }
    }

    private fun handleScheme(scheme: String?, url: String) {
        if (scheme != null) {
            if (scheme.equals("kanqiu", ignoreCase = true)) {
                handleKanQiu(url)
            } else if (scheme.equals("browser", ignoreCase = true)
                    || scheme.equals("http", ignoreCase = true)
                    || scheme.equals("https", ignoreCase = true)) {
                BrowserActivity.startActivity(context, url)
            } else if (scheme.equals("hupu", ignoreCase = true)) {
                try {
                    val `object` = JSONObject(Uri.decode(url.substring("hupu".length + 3)))
                    val method = `object`.optString("method")
                    val successcb = `object`.optString("successcb")
                    handleHuPu(method, `object`.getJSONObject("data"), successcb)
                } catch (e: Exception) {
                    e.printStackTrace()
                }

            }
        }
    }

    private fun handleKanQiu(url: String) {
        if (url.contains("topic")) {
            val uri = Uri.parse(url)
            val tid = uri.lastPathSegment
            val page = uri.getQueryParameter("page")
            val pid = uri.getQueryParameter("pid")
            ContentActivity.startActivity(context, "", tid, pid,
                    if (TextUtils.isEmpty(page)) 1 else Integer.valueOf(page))
        } else if (url.contains("board")) {
            val boardId = url.substring(url.lastIndexOf("/") + 1)
            ThreadListActivity.startActivity(context, boardId)
        } else if (url.contains("people")) {
            val uid = url.substring(url.lastIndexOf("/") + 1)
            UserProfileActivity.startActivity(context, uid)
        }
    }

    @Throws(Exception::class)
    private fun handleHuPu(method: String, data: JSONObject, successcb: String) {
        when (method) {
            "bridgeReady" -> {
                val jSONObject = JSONObject()
                try {
                    jSONObject.put("hybridVer", "1.0")
                    jSONObject.put("supportAjax", true)
                    jSONObject.put("appVer", "7.0.5.6303")
                    jSONObject.put("appName", "com.hupu.games")
                    jSONObject.put("lowDevice", false)
                    jSONObject.put("scheme", "hupu")
                    jSONObject.put("did", mRequestHelper!!.deviceId)
                    jSONObject.put("platform", "Android")
                    jSONObject.put("device", Build.PRODUCT)
                    jSONObject.put("osVer", Build.VERSION.RELEASE)
                } catch (e: JSONException) {
                    e.printStackTrace()
                }

                val js = ("javascript:HupuBridge._handle_('"
                        + successcb
                        + "','"
                        + jSONObject.toString()
                        + "','null','null');")
                loadUrl(js)
            }
            "hupu.ui.updatebbspager" -> {
                val page = data.getInt("page")
                val total = data.getInt("total")
                if (callBack != null) {
                    callBack!!.onUpdatePager(page, total)
                }
            }
            "hupu.ui.bbsreply" -> {
                val open = data.getBoolean("open")
                val extra = data.getJSONObject("extra")
                val tid = extra.getString("tid")
                val pid = extra.getLong("pid")
                val userName = extra.getString("username")
                val content = extra.getString("content")
                if (open) {
                    PostActivity.startActivity(context, Constants.TYPE_REPLY, "", tid,
                            pid.toString(), content)
                }
            }
            "hupu.album.view" -> {
                val index = data.getInt("index")
                val images = data.getJSONArray("images")
                val extraPics = ArrayList<String>()
                for (i in 0 until images.length()) {
                    val image = images.getJSONObject(i)
                    extraPics.add(image.getString("url"))
                }
                ImagePreviewActivity.startActivity(context, extraPics[index], extraPics)
            }
            "hupu.ui.copy" -> {
                val copy = data.getString("content")
                StringUtil.copy(context, copy)
            }
            "hupu.ui.report" -> {
                val reportExtra = data.getJSONObject("extra")
                val reportTid = reportExtra.getString("tid")
                val reportPid = reportExtra.getLong("pid")
                ReportActivity.startActivity(context, reportTid, reportPid.toString())
            }
            "hupu.user.login" -> {
                LoginActivity.startActivity(context)
                ToastUtil.showToast("请先登录")
            }
            "hupu.ui.pageclose" -> AppManager.appManager.finishActivity()
        }
    }

    private fun setUA(i: Int) {
        if (this.basicUA != null) {
            settings.userAgentString = this.basicUA + " isp/" + i + " network/" + i
        }
    }

    override fun loadUrl(url: String) {
        setUA(-1)
        if (header == null) {
            header = HashMap()
            header!!.put("Accept-Encoding", "gzip")
        }
        super.loadUrl(url, header)
    }

    interface HuPuWebViewCallBack {

        fun onFinish()

        fun onUpdatePager(page: Int, total: Int)

        fun onError()
    }

    override fun onScrollChanged(l: Int, t: Int, oldl: Int, oldt: Int) {
        super.onScrollChanged(l, t, oldl, oldt)

        if (onScrollChangedCallback != null) {
            onScrollChangedCallback!!.onScroll(l - oldl, t - oldt)
        }
    }

    /**
     * Impliment in the activity/fragment/view that you want to listen to the webview
     */
    interface OnScrollChangedCallback {
        fun onScroll(dx: Int, dy: Int)
    }
}
